/*******************************************************************************
* Copyright (c) 2008, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.debug.core.breakpoints;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IBreakpointImportParticipant;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.debug.core.IJavaWatchpoint;
/**
* Default implementation covering the import of all platform Java breakpoints
*
* @since 3.5
*/
public class JavaBreakpointImportParticipant implements
IBreakpointImportParticipant {
class BreakpointVerifier extends ASTVisitor {
final int TYPE = 0;
final int METHOD = 1;
final int FIELD = 2;
String fTypename = null;
String fName = null;
String fSignature = null;
IBreakpoint fBreakpoint = null;
CompilationUnit fUnit = null;
Stack<String> fTypeNameStack = null;
/**
* Constructor
*
* @param breakpoint
* @param unit
*/
public BreakpointVerifier(IBreakpoint breakpoint, CompilationUnit unit) {
fTypename = getBreakpointTypeName(breakpoint);
fName = getMemberName(breakpoint);
fSignature = getMemberSignature(breakpoint);
fBreakpoint = breakpoint;
fUnit = unit;
fTypeNameStack = new Stack<>();
}
/**
* Returns the value of the {@link JavaBreakpoint#TYPE_NAME} attribute
* from the breakpoint or <code>null</code>
*
* @param breakpoint
* @return the value of the type name attribute
*/
String getBreakpointTypeName(IBreakpoint breakpoint) {
return breakpoint.getMarker().getAttribute(
JavaBreakpoint.TYPE_NAME, null);
}
/**
* Returns the name of the member from the breakpoint attributes. The
* name will be one of (1) {@link JavaWatchpoint#FIELD_NAME}, if the
* breakpoint is a watchpoint, or (2)
* {@link JavaMethodBreakpoint#METHOD_NAME} if the breakpoint is a
* method or method entry breakpoint (3) <code>null</code> if there is
* no member name
*
* @param breakpoint
* @return the member name or <code>null</code>
*/
String getMemberName(IBreakpoint breakpoint) {
if (breakpoint instanceof IJavaWatchpoint) {
return breakpoint.getMarker().getAttribute(
JavaWatchpoint.FIELD_NAME, null);
}
return breakpoint.getMarker().getAttribute(
JavaMethodBreakpoint.METHOD_NAME, null);
}
/**
* Returns the signature of the member, defined with the
* {@link JavaMethodBreakpoint#METHOD_SIGNATURE} attribute, or
* <code>null</code>
*
* @param breakpoint
* @return the signature of the member or <code>null</code>
*/
String getMemberSignature(IBreakpoint breakpoint) {
return breakpoint.getMarker().getAttribute(
JavaMethodBreakpoint.METHOD_SIGNATURE, null);
}
/**
* Returns the fully qualified name of the enclosing type for the given
* node
*
* @param node
* @return the fully qualified name of the enclosing type
*/
private String getTypeName(ASTNode node) {
return getTypeName(node, new StringBuffer());
}
/**
* Constructs the qualified name of the enclosing parent type
*
* @param node
* the node to get the parent name for
* @param buffer
* the buffer to write the name into
* @return the fully qualified name of the parent
*/
private String getTypeName(ASTNode node, StringBuffer buffer) {
switch (node.getNodeType()) {
case ASTNode.COMPILATION_UNIT: {
CompilationUnit unit = (CompilationUnit) node;
PackageDeclaration packageDeclaration = unit.getPackage();
if (packageDeclaration != null) {
buffer.insert(0, '.');
buffer.insert(0, packageDeclaration.getName()
.getFullyQualifiedName());
}
return String.valueOf(buffer);
}
default: {
if (node instanceof AbstractTypeDeclaration) {
AbstractTypeDeclaration typeDeclaration = (AbstractTypeDeclaration) node;
ITypeBinding binding = typeDeclaration.resolveBinding();
if (binding != null) {
return binding.getBinaryName();
}
if (typeDeclaration.isPackageMemberTypeDeclaration()) {
buffer.insert(0, typeDeclaration.getName()
.getIdentifier());
} else {
buffer.insert(0, typeDeclaration.getName()
.getFullyQualifiedName());
buffer.insert(0, '$');
}
}
}
}
return getTypeName(node.getParent(), buffer);
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclaration)
*/
@Override
public boolean visit(TypeDeclaration node) {
return doTypeVisit(node);
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.TypeDeclaration)
*/
@Override
public void endVisit(TypeDeclaration node) {
doEndTypeVisit();
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumDeclaration)
*/
@Override
public boolean visit(EnumDeclaration node) {
return doTypeVisit(node);
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.EnumDeclaration)
*/
@Override
public void endVisit(EnumDeclaration node) {
doEndTypeVisit();
}
/**
* Cleans up after a type visit has ended
*/
private void doEndTypeVisit() {
if (!fTypeNameStack.isEmpty()) {
fTypeNameStack.pop();
}
}
/**
* Visits the type node and return if children should be visited
*
* @param node
* @return true if child nodes should be visited false otherwise
*/
private boolean doTypeVisit(AbstractTypeDeclaration node) {
SimpleName name = node.getName();
String typename = getTypeName(node);
fTypeNameStack.push(typename);
if (!fTypename.startsWith(typename)) {
// we are examining the wrong type stop and process other types
return false;
}
if (fBreakpoint instanceof JavaClassPrepareBreakpoint
&& name != null && typename.equals(fTypename)) {
int charstart = name.getStartPosition();
IMarker marker = fBreakpoint.getMarker();
try {
marker.setAttribute(IMarker.CHAR_START, charstart);
marker.setAttribute(IMarker.CHAR_END,
charstart + name.getLength());
} catch (CoreException ce) {
}
// found the node we were looking for, do not visit children
return false;
}
return fTypename.indexOf('$') > -1 || name != null;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldDeclaration)
*/
@Override
public boolean visit(FieldDeclaration node) {
if (!fTypename.equals(fTypeNameStack.peek())) {
return false;
}
List<VariableDeclarationFragment> fragments = node.fragments();
SimpleName name = null;
IMarker marker = fBreakpoint.getMarker();
int currentstart = marker.getAttribute(IMarker.CHAR_START, -1);
for (VariableDeclarationFragment fragment : fragments) {
name = fragment.getName();
if (name != null && name.getFullyQualifiedName().equals(fName)) {
// found field update the charstart / charend
int charstart = name.getStartPosition();
if (currentstart != charstart) {
try {
marker.setAttribute(IMarker.CHAR_START, charstart);
marker.setAttribute(IMarker.CHAR_END, charstart
+ name.getLength());
} catch (CoreException ce) {
}
}
}
}
return false;
}
/**
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
*/
@Override
public boolean visit(MethodDeclaration node) {
SimpleName name = node.getName();
String typename = fTypeNameStack.peek();
if (!fTypename.equals(typename) && !fTypename.startsWith(typename)) {
return false;
}
if (name != null && name.getFullyQualifiedName().equals(fName)) {
String sig = getMethodSignatureFromNode(node);
if (sig != null) {
sig = sig.replaceAll("\\.", "/"); //$NON-NLS-1$ //$NON-NLS-2$
if (sig.equals(fSignature)) {
IMarker marker = fBreakpoint.getMarker();
int currentstart = marker.getAttribute(
IMarker.CHAR_START, -1);
int charstart = name.getStartPosition();
if (currentstart != charstart) {
try {
marker.setAttribute(IMarker.CHAR_START,
charstart);
marker.setAttribute(IMarker.CHAR_END, charstart
+ name.getLength());
} catch (CoreException ce) {
}
}
}
}
}
// visit children in the event we have a class load breakpoint on a
// local type
return fBreakpoint instanceof JavaClassPrepareBreakpoint;
}
/**
* Creates a method signature from a specified {@link MethodDeclaration}
*
* @param node
* @return the signature for the given method node or <code>null</code>
*/
private String getMethodSignatureFromNode(MethodDeclaration node) {
Assert.isNotNull(node);
List<SingleVariableDeclaration> params = node.parameters();
List<String> rparams = getParametersTypeNames(params);
if (rparams.size() == params.size()) {
if (!node.isConstructor()) {
Type returnType = node.getReturnType2();
if (returnType != null) {
String rtype = getTypeSignature(returnType);
if (rtype != null) {
return Signature
.createMethodSignature(
rparams
.toArray(new String[rparams
.size()]), rtype);
}
}
} else {
StringBuffer buffer = new StringBuffer();
buffer.append("<init>"); //$NON-NLS-1$
collectSyntheticParam(node, rparams);
buffer.append(Signature.createMethodSignature(
rparams.toArray(new String[rparams
.size()]), Signature.SIG_VOID));
return buffer.toString();
}
}
return null;
}
/**
* Returns the listing of the signatures of the parameters passed in
*
* @param rawparams
* @return a listing of signatures for the specified parameters
*/
private List<String> getParametersTypeNames(List<SingleVariableDeclaration> rawparams) {
List<String> rparams = new ArrayList<>(rawparams.size());
String pname = null;
for (SingleVariableDeclaration param : rawparams) {
pname = getTypeSignature(param.getType());
if (pname != null) {
rparams.add(pname);
}
}
return rparams;
}
/**
* Processes the signature for the given {@link Type}
*
* @param type
* the type to process
* @return the signature for the type or <code>null</code> if one could
* not be derived
*/
private String getTypeSignature(Type type) {
ITypeBinding binding = type.resolveBinding();
if (binding == null) {
return null;
}
switch (type.getNodeType()) {
case ASTNode.PRIMITIVE_TYPE:
case ASTNode.QUALIFIED_TYPE:
case ASTNode.SIMPLE_TYPE: {
return Signature.createTypeSignature(
binding.getQualifiedName(), true);
}
case ASTNode.ARRAY_TYPE: {
ArrayType a = (ArrayType) type;
return Signature
.createArraySignature(
getTypeSignature(a.getElementType()),
a.getDimensions());
}
case ASTNode.PARAMETERIZED_TYPE: {
// we don't need to care about the other scoping types only the
// base type
return getTypeSignature(((ParameterizedType) type).getType());
}
}
return null;
}
/**
* Collects the synthetic parameter of the fully qualified name of the
* enclosing context for a constructor of an inner type
*
* @param method
* the constructor declaration
* @param rparams
* the listing of parameters to add to
*/
private void collectSyntheticParam(final MethodDeclaration method,
List<String> rparams) {
Assert.isNotNull(method);
if (isInTopLevelType(method)) {
return;
}
ASTNode parent = method.getParent();
StringBuffer name = new StringBuffer();
while (parent != null) {
parent = parent.getParent();
if (parent instanceof AbstractTypeDeclaration) {
AbstractTypeDeclaration type = (AbstractTypeDeclaration) parent;
name.insert(0, type.getName().getFullyQualifiedName());
if (type.isMemberTypeDeclaration()) {
name.insert(0, '$');
}
continue;
}
if (parent instanceof CompilationUnit) {
CompilationUnit cunit = (CompilationUnit) parent;
PackageDeclaration pdec = cunit.getPackage();
if (pdec != null) {
name.insert(0, '.');
name.insert(0, cunit.getPackage().getName()
.getFullyQualifiedName());
}
}
}
name.insert(0, "L"); //$NON-NLS-1$
name.append(';');
if (name.length() > 2) {
rparams.add(0, name.toString());
}
}
/**
* Determines if the given {@link MethodDeclaration} is present in a top
* level type
*
* @param method
* @return
*/
private boolean isInTopLevelType(final MethodDeclaration method) {
TypeDeclaration type = (TypeDeclaration) method.getParent();
return type != null && type.isPackageMemberTypeDeclaration();
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.debug.core.model.IBreakpointImportParticipant#matches(java
* .util.Map, org.eclipse.debug.core.model.IBreakpoint)
*/
@Override
public boolean matches(Map<String, Object> attributes, IBreakpoint breakpoint)
throws CoreException {
if (attributes == null || breakpoint == null) {
return false;
}
String type = (String) attributes.get("type"); //$NON-NLS-1$
if (type == null) {
return false;
}
if (!breakpoint.getMarker().getType().equals(type)) {
return false;
}
if (breakpoint instanceof JavaClassPrepareBreakpoint) {
return matchesClassBreakpoint(attributes,
(JavaClassPrepareBreakpoint) breakpoint);
}
if (breakpoint instanceof JavaExceptionBreakpoint) {
return matchesExceptionBreakpoint(attributes,
(JavaExceptionBreakpoint) breakpoint);
}
if (breakpoint instanceof JavaMethodBreakpoint) {
return matchesMethodBreakpoint(attributes,
(JavaMethodBreakpoint) breakpoint);
}
if (breakpoint instanceof JavaMethodEntryBreakpoint) {
return matchesMethodEntryBreakpoint(attributes,
(JavaMethodEntryBreakpoint) breakpoint);
}
if (breakpoint instanceof JavaWatchpoint) {
return matchesWatchpoint(attributes, (JavaWatchpoint) breakpoint);
}
if (breakpoint instanceof JavaStratumLineBreakpoint) {
return matchesStratumLineBreakpoint(attributes,
(JavaStratumLineBreakpoint) breakpoint);
}
if (breakpoint instanceof JavaPatternBreakpoint) {
return matchesPatternBreakpoint(attributes,
(JavaPatternBreakpoint) breakpoint);
}
if (breakpoint instanceof JavaTargetPatternBreakpoint) {
return matchesTargetPatternBreakpoint(attributes,
(JavaTargetPatternBreakpoint) breakpoint);
}
if (breakpoint instanceof JavaLineBreakpoint) {
return matchesLineBreakpoint(attributes,
(JavaLineBreakpoint) breakpoint);
}
return false;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.debug.core.model.IBreakpointImportParticipant#verify(org.
* eclipse.debug.core.model.IBreakpoint)
*/
@Override
public void verify(IBreakpoint breakpoint) throws CoreException {
IResource resource = breakpoint.getMarker().getResource();
CompilationUnit unit = null;
if (resource != null && resource.getType() == IResource.FILE) {
ICompilationUnit cunit = JavaCore
.createCompilationUnitFrom((IFile) resource);
if (cunit != null) {
ASTParser parser = ASTParser.newParser(AST.JLS4);
parser.setSource(cunit);
parser.setResolveBindings(true);
unit = (CompilationUnit) parser
.createAST(new NullProgressMonitor());
}
}
if (unit != null) {
if (breakpoint instanceof JavaClassPrepareBreakpoint
|| breakpoint instanceof JavaWatchpoint
|| breakpoint instanceof JavaMethodEntryBreakpoint
|| breakpoint instanceof JavaMethodBreakpoint) {
unit.accept(new BreakpointVerifier(breakpoint, unit));
} else if (breakpoint instanceof JavaLineBreakpoint) {
JavaLineBreakpoint bp = (JavaLineBreakpoint) breakpoint;
// line breakpoint use the ValidBreakpointLocationLocator to
// (re)place it
int currentline = bp.getLineNumber();
ValidBreakpointLocationLocator locator = new ValidBreakpointLocationLocator(
unit, currentline, true, true);
unit.accept(locator);
int newline = locator.getLineLocation();
if (locator.getLocationType() == ValidBreakpointLocationLocator.LOCATION_LINE) {
if (currentline != newline) {
if (locator.getFullyQualifiedTypeName() == null)
throw new CoreException(Status.CANCEL_STATUS);
bp.getMarker().setAttribute(JavaBreakpoint.TYPE_NAME,
locator.getFullyQualifiedTypeName());
bp.getMarker().setAttribute(IMarker.LINE_NUMBER,
newline);
int length = bp.getCharEnd() - bp.getCharStart();
int pos = unit.getPosition(newline, 1);
bp.getMarker().setAttribute(IMarker.CHAR_START, pos);
bp.getMarker().setAttribute(IMarker.CHAR_END,
pos + length);
}
} else {
// the line breakpoint will not be a line breakpoint anymore
// get rid of it
throw new CoreException(Status.CANCEL_STATUS);
}
}
}
}
/**
* Compares two attributes in a <code>null</code> safe way
*
* @param attr1
* the first attribute
* @param attr2
* the second attribute
* @return true if the attributes are equal, false otherwise. If both
* attributes are <code>null</code> they are considered to be equal
*/
private boolean attributesEqual(Object attr1, Object attr2) {
if (attr1 == null) {
return attr2 == null;
}
if (attr2 == null) {
return false;
}
return attr1.equals(attr2);
}
/**
* Returns if the given map of attributes matches the given line breakpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the breakpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesLineBreakpoint(Map<String, Object> attributes,
JavaLineBreakpoint breakpoint) throws CoreException {
Integer line = (Integer) attributes.get(IMarker.LINE_NUMBER);
return breakpoint.getLineNumber() == (line == null ? -1 : line.intValue())
&& attributesEqual(breakpoint.getTypeName(), attributes.get(JavaBreakpoint.TYPE_NAME));
}
/**
* Returns if the given map of attributes matches the given class prepare
* breakpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the breakpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesClassBreakpoint(Map<String, Object> attributes,
JavaClassPrepareBreakpoint breakpoint) throws CoreException {
Integer type = (Integer) attributes
.get(JavaClassPrepareBreakpoint.MEMBER_TYPE);
return attributesEqual(breakpoint.getTypeName(),
attributes.get(JavaBreakpoint.TYPE_NAME))
&& breakpoint.getMemberType() == (type == null ? -1 : type
.intValue());
}
/**
* Returns if the given map of attributes matches the given exception
* breakpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the breakpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesExceptionBreakpoint(Map<String, Object> attributes,
JavaExceptionBreakpoint breakpoint) throws CoreException {
return attributesEqual(breakpoint.getTypeName(),
attributes.get(JavaBreakpoint.TYPE_NAME));
}
/**
* Returns if the given map of attributes matches the given method
* breakpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the breakpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesMethodBreakpoint(Map<String, Object> attributes,
JavaMethodBreakpoint breakpoint) throws CoreException {
return attributesEqual(breakpoint.getTypeName(),
attributes.get(JavaBreakpoint.TYPE_NAME))
&& attributesEqual(breakpoint.getMethodName(),
attributes.get(JavaMethodBreakpoint.METHOD_NAME))
&& attributesEqual(breakpoint.getMethodSignature(),
attributes.get(JavaMethodBreakpoint.METHOD_SIGNATURE));
}
/**
* Returns if the given map of attributes matches the given method entry
* breakpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the breakpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesMethodEntryBreakpoint(Map<String, Object> attributes,
JavaMethodEntryBreakpoint breakpoint) throws CoreException {
return attributesEqual(breakpoint.getTypeName(),
attributes.get(JavaBreakpoint.TYPE_NAME))
&& attributesEqual(breakpoint.getMethodName(),
attributes.get(JavaMethodBreakpoint.METHOD_NAME))
&& attributesEqual(breakpoint.getMethodSignature(),
attributes.get(JavaMethodBreakpoint.METHOD_SIGNATURE));
}
/**
* Returns if the given map of attributes matches the given watchpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the watchpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesWatchpoint(Map<String, Object> attributes, JavaWatchpoint watchpoint)
throws CoreException {
return watchpoint.getFieldName().equals(
attributes.get(JavaWatchpoint.FIELD_NAME))
&& attributesEqual(watchpoint.getTypeName(),
attributes.get(JavaBreakpoint.TYPE_NAME));
}
/**
* Returns if the given map of attributes matches the given stratum line
* breakpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the breakpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesStratumLineBreakpoint(Map<String, Object> attributes,
JavaStratumLineBreakpoint breakpoint) throws CoreException {
Integer line = (Integer) attributes.get(IMarker.LINE_NUMBER);
return breakpoint.getLineNumber() == (line == null ? -1 : line
.intValue())
&& attributesEqual(breakpoint.getSourceName(),
attributes.get(JavaLineBreakpoint.SOURCE_NAME))
&& attributesEqual(breakpoint.getStratum(),
attributes.get(JavaStratumLineBreakpoint.STRATUM))
&& attributesEqual(breakpoint.getSourcePath(),
attributes.get(JavaStratumLineBreakpoint.SOURCE_PATH));
}
/**
* Returns if the given map of attributes matches the given pattern
* breakpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the breakpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesPatternBreakpoint(Map<String, Object> attributes,
JavaPatternBreakpoint breakpoint) throws CoreException {
Integer line = (Integer) attributes.get(IMarker.LINE_NUMBER);
return breakpoint.getLineNumber() == (line == null ? -1 : line
.intValue())
&& attributesEqual(breakpoint.getSourceName(),
attributes.get(JavaLineBreakpoint.SOURCE_NAME)) &&
// TDOD comparing pattern too restrictive??
breakpoint.getPattern().equals(
attributes.get(JavaPatternBreakpoint.PATTERN));
}
/**
* Returns if the given map of attributes matches the given target pattern
* breakpoint
*
* @param attributes
* @param breakpoint
* @return true if the attributes match the breakpoints' attributes, false
* otherwise
* @throws CoreException
*/
private boolean matchesTargetPatternBreakpoint(Map<String, Object> attributes,
JavaTargetPatternBreakpoint breakpoint) throws CoreException {
Integer line = (Integer) attributes.get(IMarker.LINE_NUMBER);
return breakpoint.getLineNumber() == (line == null ? -1 : line
.intValue())
&& attributesEqual(breakpoint.getTypeName(),
attributes.get(JavaBreakpoint.TYPE_NAME))
&& attributesEqual(breakpoint.getSourceName(),
attributes.get(JavaLineBreakpoint.SOURCE_NAME));
}
}